package main

import (
	"database/sql"
	"net/http"

	"time"

	"github.com/gin-gonic/gin"
	_ "github.com/go-sql-driver/mysql"
	"github.com/google/uuid"
)

type User struct {
	ID   string `json:"id" db:"id"`
	Name string `json:"name" db:"name"`
	Age  int    `json:"age" db:"age"`
}

var db *sql.DB

func main() {
	// 初始化数据库连接
	initDB()
	defer db.Close()

	router := gin.Default()

	// 设置模板目录
	router.LoadHTMLGlob("templates/*")

	// 静态文件服务
	router.Static("/static", "./static")

	// 登录路由（放在最前面）
	router.GET("/login", loginHandler)  // 已正确注册GET路由
	router.POST("/login", loginSubmitHandler)
	
	// 查询页面路由
	router.GET("/query", queryHandler)
	router.GET("/api/users/:id", getUserAPI) // 添加查询API

	// 需要登录验证的路由组
	auth := router.Group("/")
	auth.Use(authMiddleware())
	{
		auth.GET("/", indexHandler)       // 将首页路由移入认证组
		auth.GET("/users", usersHandler)
		auth.GET("/api", apiHandler)  
		auth.GET("/users/edit/:id", editUserHandler)
	}

	// 将以下路由移到路由组外
	router.POST("/api/users", createUser)
	router.DELETE("/api/users/:id", deleteUser)
	router.POST("/users/update", updateUser)

	// 404处理应放在最后
	router.NoRoute(func(c *gin.Context) {
		c.HTML(http.StatusNotFound, "404.html", nil)
	})

	router.Run(":8080")  // 确保这行在路由组外
}

func initDB() {
	var err error
	dsn := "root:root@tcp(127.0.0.1:3306)/golang?charset=utf8mb4&parseTime=True"
	db, err = sql.Open("mysql", dsn)
	if err != nil {
		panic(err)
	}

	// Add connection pool settings
	db.SetMaxOpenConns(25)
	db.SetMaxIdleConns(25)
	db.SetConnMaxLifetime(5 * time.Minute)

	err = db.Ping()
	if err != nil {
		panic(err)
	}

	// 创建users表
	createTableSQL := `
	CREATE TABLE IF NOT EXISTS users (
		id VARCHAR(36) PRIMARY KEY,
		name VARCHAR(255) NOT NULL,
		age INT NOT NULL
	)`
	_, err = db.Exec(createTableSQL)
	if err != nil {
		panic(err)
	}
}

func indexHandler(c *gin.Context) {
	c.HTML(http.StatusOK, "index.html", gin.H{
		"title": "用户管理系统",
	})
}

func usersHandler(c *gin.Context) {
	users, err := getAllUsers()
	if err != nil {
		c.Error(err) // Add error to context
		c.HTML(http.StatusInternalServerError, "error.html", gin.H{
			"message": "Failed to retrieve users",
		})
		return
	}

	c.HTML(http.StatusOK, "users.html", gin.H{
		"title": "用户列表",
		"users": users,
	})
}

func editUserHandler(c *gin.Context) {
	id := c.Param("id")
	user, err := getUserByID(id)
	if err != nil {
		c.Redirect(http.StatusFound, "/users")
		return
	}

	c.HTML(http.StatusOK, "edit_user.html", gin.H{
		"title": "编辑用户",
		"user":  user,
	})
}

// 数据库操作函数
func getAllUsers() ([]User, error) {
	rows, err := db.Query("SELECT id, name, age FROM users")
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var users []User
	for rows.Next() {
		var user User
		err := rows.Scan(&user.ID, &user.Name, &user.Age)
		if err != nil {
			return nil, err
		}
		users = append(users, user)
	}
	return users, nil
}

func getUserByID(id string) (*User, error) {
	row := db.QueryRow("SELECT id, name, age FROM users WHERE id = ?", id)

	user := &User{}
	err := row.Scan(&user.ID, &user.Name, &user.Age)
	if err != nil {
		return nil, err
	}
	return user, nil
}

// API处理函数
func createUser(c *gin.Context) {
	var user User
	if err := c.ShouldBindJSON(&user); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request format"})
		return
	}

	// Generate UUID if not provided
	if user.ID == "" {
		user.ID = uuid.New().String()
	}

	// Validate input
	if user.Name == "" || user.Age <= 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Name and age are required"})
		return
	}

	_, err := db.Exec("INSERT INTO users (id, name, age) VALUES (?, ?, ?)",
		user.ID, user.Name, user.Age)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusCreated, user)
}

func deleteUser(c *gin.Context) {
	id := c.Param("id")

	result, err := db.Exec("DELETE FROM users WHERE id = ?", id)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	rowsAffected, _ := result.RowsAffected()
	if rowsAffected == 0 {
		c.JSON(http.StatusNotFound, gin.H{"error": "user not found"})
		return
	}

	c.Status(http.StatusNoContent)
}

func updateUser(c *gin.Context) {
	var user User
	if err := c.ShouldBind(&user); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	_, err := db.Exec("UPDATE users SET name = ?, age = ? WHERE id = ?",
		user.Name, user.Age, user.ID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.Redirect(http.StatusFound, "/users")
}

// 新增登录处理函数
func loginHandler(c *gin.Context) {
	c.HTML(http.StatusOK, "login.html", gin.H{
		"title": "管理员登录",
	})
}

// 新增登录提交处理
func loginSubmitHandler(c *gin.Context) {
    userId := c.PostForm("user_id")  // 确保字段名匹配
    password := c.PostForm("password")

    // 硬编码验证（实际应查询数据库）
    if userId == "admin" && password == "admin123" {
        c.SetCookie("auth", "true", 3600, "/", "", false, true)
        c.Redirect(http.StatusFound, "/")
        return
    }

	c.HTML(http.StatusUnauthorized, "login.html", gin.H{
		"title":   "管理员登录",
		"message": "用户名或密码错误",
	})
}

// 新增认证中间件
func authMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		if cookie, err := c.Cookie("auth"); err != nil || cookie != "true" {
			c.Redirect(http.StatusFound, "/login")
			c.Abort()
			return
		}
		c.Next()
	}
}

// 新增用户查询API
func getUserAPI(c *gin.Context) {
	id := c.Param("id")
	user, err := getUserByID(id)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "用户不存在"})
		return
	}
	c.JSON(http.StatusOK, user)
}

// 新增查询页面处理
func queryHandler(c *gin.Context) {
	c.HTML(http.StatusOK, "query.html", gin.H{
		"title": "用户信息查询",
	})
}

func apiHandler(c *gin.Context) {
    c.HTML(http.StatusOK, "api.html", gin.H{
        "title": "第六组成员",
    })
}
